#include "db_page.h"
#include <stdexcept> // 用于 std::runtime_error
#include <cstring>   // 用于 std::memcpy
#include <iostream>
// 定义新的类型标签，用于序列化
constexpr uint8_t TAG_NULL = 0x00;
constexpr uint8_t TAG_BOOL = 0x01;
// 有符号整数
constexpr uint8_t TAG_INT8 = 0x10;
constexpr uint8_t TAG_INT16 = 0x11;
constexpr uint8_t TAG_INT32 = 0x12;
constexpr uint8_t TAG_INT64 = 0x13;
// 无符号整数
constexpr uint8_t TAG_UINT8 = 0x20;
constexpr uint8_t TAG_UINT16 = 0x21;
constexpr uint8_t TAG_UINT32 = 0x22;
constexpr uint8_t TAG_UINT64 = 0x23;
// 浮点数
constexpr uint8_t TAG_FLOAT = 0x30;
constexpr uint8_t TAG_DOUBLE = 0x31;
// 变长类型
constexpr uint8_t TAG_STRING = 0x40;

// ------------------- 构造函数和初始化 -------------------

DBPage::DBPage() : data_(REAL_PAGE_SIZE, 0) {}

DBPage::DBPage(std::vector<uint8_t> &&data) : data_(std::move(data))
{
    if (data_.size() != REAL_PAGE_SIZE)
    {
        throw std::invalid_argument("构造Page失败: 数据大小不等于PAGE_SIZE");
    }
}

void DBPage::initialize(uint32_t page_id, PageType page_type, uint16_t level, uint32_t parent_page_id)
{
    PageHeader *header = getHeader();
    std::memset(data_.data(), 0, REAL_PAGE_SIZE); // 清空整个页
    header->page_id = page_id;
    header->parent_page_id = parent_page_id;
    header->page_type = page_type;
    header->level = level;
    header->num_records = 0;
    header->free_space_ptr = sizeof(PageHeader);
    header->prev_page_id = INVALID_PAGE_ID;
    header->next_page_id = INVALID_PAGE_ID;
    updateChecksum();
}

// ------------------- 私有辅助函数 -------------------

uint32_t DBPage::getFreeSpaceSize() const
{
    const PageHeader *header = getHeader();
    // 空闲空间从free_space_ptr开始，到槽数组开始处结束
    uint32_t slot_array_start = REAL_PAGE_SIZE - header->num_records * sizeof(Slot);
    return slot_array_start - header->free_space_ptr;
}

// 计算一行序列化后的大小
size_t DBPage::calculateRowSize(const Row &row) const
{
    size_t size = 0;
    for (const auto &val : row)
    {
        if (!val.has_value())
        {                            // 处理 NULL
            size += sizeof(uint8_t); // 仅类型标签
        }
        else
        {
            // 访问 variant 内部的值
            std::visit([&size](auto &&arg)
                       {
                using T = std::decay_t<decltype(arg)>;
                size += sizeof(uint8_t); // 类型标签
                if constexpr (std::is_same_v<T, bool>)     size += sizeof(bool);
                else if constexpr (std::is_same_v<T, int8_t>)   size += sizeof(int8_t);
                else if constexpr (std::is_same_v<T, int16_t>)  size += sizeof(int16_t);
                else if constexpr (std::is_same_v<T, int32_t>)  size += sizeof(int32_t);
                else if constexpr (std::is_same_v<T, int64_t>)  size += sizeof(int64_t);
                else if constexpr (std::is_same_v<T, uint8_t>)  size += sizeof(uint8_t);
                else if constexpr (std::is_same_v<T, uint16_t>) size += sizeof(uint16_t);
                else if constexpr (std::is_same_v<T, uint32_t>) size += sizeof(uint32_t);
                else if constexpr (std::is_same_v<T, uint64_t>) size += sizeof(uint64_t);
                else if constexpr (std::is_same_v<T, float>)    size += sizeof(float);
                else if constexpr (std::is_same_v<T, double>)   size += sizeof(double);
                else if constexpr (std::is_same_v<T, std::string>) {
                    size += sizeof(uint32_t); // 字符串长度
                    size += arg.size();      // 字符串数据
                } }, val.value());
        }
    }
    return size;
}

// --- [MODIFIED] ---
// 将一行序列化到缓冲区
void DBPage::serializeRow(uint8_t *buffer, const Row &row) const
{
    uint8_t *ptr = buffer;
    for (const auto &val : row)
    {
        if (!val.has_value())
        { // 处理 NULL
            *ptr++ = TAG_NULL;
        }
        else
        {
            // 访问 variant 内部的值
            std::visit([&ptr](auto &&arg)
                       {
                using T = std::decay_t<decltype(arg)>;
                if constexpr (std::is_same_v<T, bool>) { *ptr++ = TAG_BOOL; std::memcpy(ptr, &arg, sizeof(T)); ptr += sizeof(T); }
                else if constexpr (std::is_same_v<T, int8_t>) { *ptr++ = TAG_INT8; std::memcpy(ptr, &arg, sizeof(T)); ptr += sizeof(T); }
                else if constexpr (std::is_same_v<T, int16_t>) { *ptr++ = TAG_INT16; std::memcpy(ptr, &arg, sizeof(T)); ptr += sizeof(T); }
                else if constexpr (std::is_same_v<T, int32_t>) { *ptr++ = TAG_INT32; std::memcpy(ptr, &arg, sizeof(T)); ptr += sizeof(T); }
                else if constexpr (std::is_same_v<T, int64_t>) { *ptr++ = TAG_INT64; std::memcpy(ptr, &arg, sizeof(T)); ptr += sizeof(T); }
                else if constexpr (std::is_same_v<T, uint8_t>) { *ptr++ = TAG_UINT8; std::memcpy(ptr, &arg, sizeof(T)); ptr += sizeof(T); }
                else if constexpr (std::is_same_v<T, uint16_t>) { *ptr++ = TAG_UINT16; std::memcpy(ptr, &arg, sizeof(T)); ptr += sizeof(T); }
                else if constexpr (std::is_same_v<T, uint32_t>) { *ptr++ = TAG_UINT32; std::memcpy(ptr, &arg, sizeof(T)); ptr += sizeof(T); }
                else if constexpr (std::is_same_v<T, uint64_t>) { *ptr++ = TAG_UINT64; std::memcpy(ptr, &arg, sizeof(T)); ptr += sizeof(T); }
                else if constexpr (std::is_same_v<T, float>) { *ptr++ = TAG_FLOAT; std::memcpy(ptr, &arg, sizeof(T)); ptr += sizeof(T); }
                else if constexpr (std::is_same_v<T, double>) { *ptr++ = TAG_DOUBLE; std::memcpy(ptr, &arg, sizeof(T)); ptr += sizeof(T); }
                else if constexpr (std::is_same_v<T, std::string>) {
                    *ptr++ = TAG_STRING;
                    uint32_t len = arg.size();
                    std::memcpy(ptr, &len, sizeof(uint32_t));
                    ptr += sizeof(uint32_t);
                    std::memcpy(ptr, arg.data(), len);
                    ptr += len;
                } }, val.value());
        }
    }
}

// --- [MODIFIED] ---
// 从缓冲区反序列化一行
void DBPage::deserializeRow(const uint8_t *buffer, uint16_t size, Row &row) const
{
    row.clear();
    const uint8_t *ptr = buffer;
    const uint8_t *end = buffer + size;
    while (ptr < end)
    {
        uint8_t type_tag = *ptr++;
        switch (type_tag)
        {
        case TAG_NULL:
        {
            row.emplace_back(std::nullopt);
            break;
        }
        case TAG_BOOL:
        {
            bool v;
            std::memcpy(&v, ptr, sizeof(v));
            row.emplace_back(ValueType(v));
            ptr += sizeof(v);
            break;
        }
        case TAG_INT8:
        {
            int8_t v;
            std::memcpy(&v, ptr, sizeof(v));
            row.emplace_back(ValueType(v));
            ptr += sizeof(v);
            break;
        }
        case TAG_INT16:
        {
            int16_t v;
            std::memcpy(&v, ptr, sizeof(v));
            row.emplace_back(ValueType(v));
            ptr += sizeof(v);
            break;
        }
        case TAG_INT32:
        {
            int32_t v;
            std::memcpy(&v, ptr, sizeof(v));
            row.emplace_back(ValueType(v));
            ptr += sizeof(v);
            break;
        }
        case TAG_INT64:
        {
            int64_t v;
            std::memcpy(&v, ptr, sizeof(v));
            row.emplace_back(ValueType(v));
            ptr += sizeof(v);
            break;
        }
        case TAG_UINT8:
        {
            uint8_t v;
            std::memcpy(&v, ptr, sizeof(v));
            row.emplace_back(ValueType(v));
            ptr += sizeof(v);
            break;
        }
        case TAG_UINT16:
        {
            uint16_t v;
            std::memcpy(&v, ptr, sizeof(v));
            row.emplace_back(ValueType(v));
            ptr += sizeof(v);
            break;
        }
        case TAG_UINT32:
        {
            uint32_t v;
            std::memcpy(&v, ptr, sizeof(v));
            row.emplace_back(ValueType(v));
            ptr += sizeof(v);
            break;
        }
        case TAG_UINT64:
        {
            uint64_t v;
            std::memcpy(&v, ptr, sizeof(v));
            row.emplace_back(ValueType(v));
            ptr += sizeof(v);
            break;
        }
        case TAG_FLOAT:
        {
            float v;
            std::memcpy(&v, ptr, sizeof(v));
            row.emplace_back(ValueType(v));
            ptr += sizeof(v);
            break;
        }
        case TAG_DOUBLE:
        {
            double v;
            std::memcpy(&v, ptr, sizeof(v));
            row.emplace_back(ValueType(v));
            ptr += sizeof(v);
            break;
        }
        case TAG_STRING:
        {
            uint32_t len;
            std::memcpy(&len, ptr, sizeof(uint32_t));
            ptr += sizeof(uint32_t);
            row.emplace_back(ValueType(std::string(reinterpret_cast<const char *>(ptr), len)));
            ptr += len;
            break;
        }
        default:
        {
            throw std::runtime_error("反序列化行时遇到未知类型标签");
        }
        }
    }
}
// 计算一个 B+树键序列化后的大小
size_t DBPage::getSerializedKeySize(const BPlusTreeKey &key) const
{
    if (!key.has_value())
    {
        throw std::invalid_argument("B+树的键不能为 NULL");
    }

    size_t size = 0;
    std::visit([&size](auto &&arg)
               {
        using T = std::decay_t<decltype(arg)>;
        size += sizeof(uint8_t); // 类型标签
        if constexpr (std::is_same_v<T, bool>)     size += sizeof(bool);
        else if constexpr (std::is_same_v<T, int8_t>)   size += sizeof(int8_t);
        else if constexpr (std::is_same_v<T, int16_t>)  size += sizeof(int16_t);
        else if constexpr (std::is_same_v<T, int32_t>)  size += sizeof(int32_t);
        else if constexpr (std::is_same_v<T, int64_t>)  size += sizeof(int64_t);
        else if constexpr (std::is_same_v<T, uint8_t>)  size += sizeof(uint8_t);
        else if constexpr (std::is_same_v<T, uint16_t>) size += sizeof(uint16_t);
        else if constexpr (std::is_same_v<T, uint32_t>) size += sizeof(uint32_t);
        else if constexpr (std::is_same_v<T, uint64_t>) size += sizeof(uint64_t);
        else if constexpr (std::is_same_v<T, float>)    size += sizeof(float);
        else if constexpr (std::is_same_v<T, double>)   size += sizeof(double);
        else if constexpr (std::is_same_v<T, std::string>) {
            size += sizeof(uint32_t); // 字符串长度前缀
            size += arg.length();
        } }, key.value());
    return size;
}

// --- [MODIFIED] ---
// 将一个 B+树键序列化到缓冲区
void DBPage::serializeKey(uint8_t *buffer, const BPlusTreeKey &key) const
{
    if (!key.has_value())
    {
        throw std::invalid_argument("B+树的键不能为 NULL");
    }

    uint8_t *ptr = buffer;
    std::visit([&ptr](auto &&arg)
               {
        using T = std::decay_t<decltype(arg)>;
        if constexpr (std::is_same_v<T, bool>) { *ptr++ = TAG_BOOL; std::memcpy(ptr, &arg, sizeof(T)); }
        else if constexpr (std::is_same_v<T, int8_t>) { *ptr++ = TAG_INT8; std::memcpy(ptr, &arg, sizeof(T)); }
        else if constexpr (std::is_same_v<T, int16_t>) { *ptr++ = TAG_INT16; std::memcpy(ptr, &arg, sizeof(T)); }
        else if constexpr (std::is_same_v<T, int32_t>) { *ptr++ = TAG_INT32; std::memcpy(ptr, &arg, sizeof(T)); }
        else if constexpr (std::is_same_v<T, int64_t>) { *ptr++ = TAG_INT64; std::memcpy(ptr, &arg, sizeof(T)); }
        else if constexpr (std::is_same_v<T, uint8_t>) { *ptr++ = TAG_UINT8; std::memcpy(ptr, &arg, sizeof(T)); }
        else if constexpr (std::is_same_v<T, uint16_t>) { *ptr++ = TAG_UINT16; std::memcpy(ptr, &arg, sizeof(T)); }
        else if constexpr (std::is_same_v<T, uint32_t>) { *ptr++ = TAG_UINT32; std::memcpy(ptr, &arg, sizeof(T)); }
        else if constexpr (std::is_same_v<T, uint64_t>) { *ptr++ = TAG_UINT64; std::memcpy(ptr, &arg, sizeof(T)); }
        else if constexpr (std::is_same_v<T, float>) { *ptr++ = TAG_FLOAT; std::memcpy(ptr, &arg, sizeof(T)); }
        else if constexpr (std::is_same_v<T, double>) { *ptr++ = TAG_DOUBLE; std::memcpy(ptr, &arg, sizeof(T)); }
        else if constexpr (std::is_same_v<T, std::string>) {
            *ptr++ = TAG_STRING;
            uint32_t len = arg.length();
            std::memcpy(ptr, &len, sizeof(uint32_t));
            ptr += sizeof(uint32_t);
            std::memcpy(ptr, arg.data(), len);
        } }, key.value());
}

// --- [MODIFIED] ---
// 从缓冲区反序列化一个 B+树键
BPlusTreeKey DBPage::deserializeKey(const uint8_t *buffer) const
{
    const uint8_t *ptr = buffer;
    uint8_t type_tag = *ptr++;

    switch (type_tag)
    {
    case TAG_NULL:
    {
        throw std::runtime_error("A NULL tag was found when deserializing the key");
    }
    case TAG_BOOL:
    {
        bool v;
        std::memcpy(&v, ptr, sizeof(v));
        return ValueType(v);
    }
    case TAG_INT8:
    {
        int8_t v;
        std::memcpy(&v, ptr, sizeof(v));
        return ValueType(v);
    }
    case TAG_INT16:
    {
        int16_t v;
        std::memcpy(&v, ptr, sizeof(v));
        return ValueType(v);
    }
    case TAG_INT32:
    {
        int32_t v;
        std::memcpy(&v, ptr, sizeof(v));
        return ValueType(v);
    }
    case TAG_INT64:
    {
        int64_t v;
        std::memcpy(&v, ptr, sizeof(v));
        return ValueType(v);
    }
    case TAG_UINT8:
    {
        uint8_t v;
        std::memcpy(&v, ptr, sizeof(v));
        return ValueType(v);
    }
    case TAG_UINT16:
    {
        uint16_t v;
        std::memcpy(&v, ptr, sizeof(v));
        return ValueType(v);
    }
    case TAG_UINT32:
    {
        uint32_t v;
        std::memcpy(&v, ptr, sizeof(v));
        return ValueType(v);
    }
    case TAG_UINT64:
    {
        uint64_t v;
        std::memcpy(&v, ptr, sizeof(v));
        return ValueType(v);
    }
    case TAG_FLOAT:
    {
        float v;
        std::memcpy(&v, ptr, sizeof(v));
        return ValueType(v);
    }
    case TAG_DOUBLE:
    {
        double v;
        std::memcpy(&v, ptr, sizeof(v));
        return ValueType(v);
    }
    case TAG_STRING:
    {
        uint32_t len;
        std::memcpy(&len, ptr, sizeof(uint32_t));
        ptr += sizeof(uint32_t);
        return ValueType(std::string(reinterpret_cast<const char *>(ptr), len));
    }
    default:
    {
        throw std::runtime_error("反序列化键时遇到未知类型标签");
    }
    }
}
/**
 * @brief 将当前页的后半部分记录移动到 recipient 页。
 *        如果是内部节点，中间键会被返回，并且不会被移动。
 * @param recipient 接收记录的目标页。
 * @return std::optional<BPlusTreeKey> 如果是内部分裂，返回需要提拔的键。
 */
std::optional<BPlusTreeKey> DBPage::MoveHalfTo(DBPage *recipient)
{
    int total_records = getNumRecords();
    int middle_index = total_records / 2;

    std::optional<BPlusTreeKey> key_to_promote = std::nullopt;

    // 对于内部节点，中间键需要被提拔
    if (!isLeaf())
    {
        key_to_promote = getKey(middle_index);

        uint32_t new_leftmost_ptr = getInternalValue(middle_index);
        recipient->setLeftmostPointer(new_leftmost_ptr);
    }

    // 决定从哪个索引开始移动
    // 叶子节点：移动 middle_index 及之后的所有记录
    // 内部节点：移动 middle_index + 1 及之后的所有记录 (中间键不移动)
    int start_move_index = isLeaf() ? middle_index : middle_index + 1;

    // 从后往前移动记录
    for (int i = total_records - 1; i >= start_move_index; --i)
    {
        auto [record_ptr, record_size] = GetRecord(i);
        bool is_space_enough = true;
        recipient->insertRecord(0, record_ptr, record_size, is_space_enough);
        DeleteRecord(i);
    }

    // 对于内部节点，分裂后需要删除原节点中的中间键
    if (!isLeaf())
    {
        DeleteRecord(middle_index);
    }

    return key_to_promote;
}
bool DBPage::insertRecord(int index, const uint8_t *record_data, uint16_t record_size, bool &is_space_enough)
{
    if (getFreeSpaceSize() < record_size + sizeof(Slot))
    {
        is_space_enough = false; // 空间不足
        return false;
    }

    PageHeader *header = getHeader();

    // 移动现有槽以腾出新槽的空间
    // 我们在`index`处插入，所以移动槽[index, num_records-1]
    int num_slots_to_move = header->num_records - index;
    if (num_slots_to_move > 0)
    {
        uint8_t *dest = reinterpret_cast<uint8_t *>(getSlot(header->num_records));
        uint8_t *src = reinterpret_cast<uint8_t *>(getSlot(header->num_records - 1));
        std::memmove(dest, src, num_slots_to_move * sizeof(Slot));
    }

    // 将新记录数据写入空闲空间区域
    std::memcpy(data_.data() + header->free_space_ptr, record_data, record_size);

    // 创建新槽
    Slot *new_slot = getSlot(index);
    new_slot->offset = header->free_space_ptr;
    new_slot->size = record_size;

    std::cout << "index:" << index << "offset:" << new_slot->offset << "size:" << new_slot->size << std::endl;
    // 更新页头
    header->free_space_ptr += record_size;
    header->num_records++;

    updateChecksum();
    return true;
}

// 获取记录的原始数据指针和大小
std::pair<const uint8_t *, uint16_t> DBPage::GetRecord(int index) const
{
    const Slot *slot = getSlot(index);
    return {getRecordData(index), slot->size};
}

void DBPage::DeleteRecord(int index)
{
    uint16_t records = getNumRecords();
    if (index < 0 || index >= records)
        return;

    // 1. 获取要删除的记录信息
    PageHeader *header = getHeader();
    Slot *slot_to_delete = getSlot(index);
    uint16_t offset = slot_to_delete->offset;
    uint16_t size = slot_to_delete->size;

    // 2. 将该记录之后的所有记录数据向前移动，填补空隙
    uint8_t *dest = data_.data() + offset;
    uint8_t *src = dest + size;
    size_t bytes_to_move = header->free_space_ptr - (offset + size);
    if (bytes_to_move > 0)
    {
        std::memmove(dest, src, bytes_to_move);
    }

    // 3. 数值往前移
    for (int i = 0; i < records - 1; ++i)
    {
        Slot *current_slot = getSlot(i);
        if (i < index && current_slot->offset > offset)
        {
            current_slot->offset -= size;
        }
        else if (i >= index)
        {
            Slot *next_slot = getSlot(i + 1);
            current_slot->offset = next_slot->offset > offset ? next_slot->offset - size : next_slot->offset;
            current_slot->size = next_slot->size;
        }
        std::cout << "after change" << "index:" << i << "offset:" << current_slot->offset << "size:" << current_slot->size << std::endl;
    }
    // 4.删除最后一个槽(数据全置0)
    Slot *last_slot = getSlot(records - 1);
    std::memset(last_slot, 0, sizeof(Slot));
    // 5. 更新页头中的记录数 (在更新槽之前，这样循环的边界就是正确的)
    header->num_records--;
    header->free_space_ptr -= size;
    // 6. 更新校验和
    updateChecksum();
}

// ------------------- 内部节点API -------------------

BPlusTreeKey DBPage::getInternalKey(int index) const
{
    return getKey(index);
}
bool DBPage::checkSpaceForLeafInsertion(const BPlusTreeKey &key, const std::variant<Row, BPlusTreeKey> &value) const
{
    size_t key_size = getSerializedKeySize(key);
    size_t value_size = std::visit([&](auto &&arg)
                                   {
            using T = std::decay_t<decltype(arg)>;
            if constexpr (std::is_same_v<T, Row>) {
                return calculateRowSize(arg);
            } else { // BPlusTreeKey
                return getSerializedKeySize(arg);
            } }, value);
    size_t record_size = key_size + value_size;
    size_t required_space = record_size + sizeof(Slot);
    return getFreeSpaceSize() >= required_space;
}
bool DBPage::checkSpaceForInternalInsertion(const BPlusTreeKey &key) const
{
    size_t key_size = getSerializedKeySize(key);
    size_t record_size = key_size + sizeof(uint32_t);
    size_t required_space = record_size + sizeof(Slot);
    return getFreeSpaceSize() >= required_space;
}
uint32_t DBPage::getInternalValue(int index) const
{
    const uint8_t *record_ptr = getRecordData(index);
    // Get the key first to figure out its size
    BPlusTreeKey key = deserializeKey(record_ptr);
    size_t key_size = getSerializedKeySize(key);

    uint32_t page_id;
    // The value starts right after the serialized key
    std::memcpy(&page_id, record_ptr + key_size, sizeof(uint32_t));
    return page_id;
}

int DBPage::findInternalKeyIndex(BPlusTreeKey key) const
{
    int low = 0, high = getNumRecords() - 1;
    if (!key.has_value())
        return -1;

    while (low <= high)
    {
        int mid = low + (high - low) / 2;
        // *** MODIFIED COMPARISON ***
        int cmp = compareKeys(getInternalKey(mid), key);

        if (cmp == 0) // getInternalKey(mid) == key
        {
            return mid;
        }
        if (cmp < 0) // getInternalKey(mid) < key
        {
            low = mid + 1;
        }
        else // getInternalKey(mid) > key
        {
            high = mid - 1;
        }
    }
    return -1; // 未找到
}

bool DBPage::insertInternal(BPlusTreeKey key, uint32_t child_page_id, bool &is_space_enough)
{
    size_t key_size = getSerializedKeySize(key);
    size_t record_size = key_size + sizeof(uint32_t);
    std::vector<uint8_t> record_buffer(record_size);

    serializeKey(record_buffer.data(), key);
    std::memcpy(record_buffer.data() + key_size, &child_page_id, sizeof(uint32_t));

    int insert_idx = 0;
    while (insert_idx < getNumRecords() && getKey(insert_idx) < key)
    {
        insert_idx++;
    }

    return insertRecord(insert_idx, record_buffer.data(), record_size, is_space_enough);
}

// ------------------- 叶子节点API -------------------

BPlusTreeKey DBPage::getLeafKey(int index) const
{
    return getKey(index);
}

bool DBPage::getLeafValue(int index, Row &row) const
{
    const Slot *slot = getSlot(index);
    const uint8_t *record_ptr = getRecordData(index);
    BPlusTreeKey key = deserializeKey(record_ptr);
    auto key_size = getSerializedKeySize(key);

    uint16_t row_data_size = slot->size - key_size;
    const uint8_t *row_data_ptr = record_ptr + key_size;

    try
    {
        deserializeRow(row_data_ptr, row_data_size, row);
    }
    catch (const std::exception &)
    {
        return false;
    }
    return true;
}

/**
 * @brief (二级索引专用) 获取叶子节点的值，即主键。
 * @param index 记录的索引。
 * @return BPlusTreeKey 主键。
 */
BPlusTreeKey DBPage::getLeafValue(int index) const
{
    const uint8_t *record_ptr = getRecordData(index);
    // 反序列化二级索引键以确定其大小
    BPlusTreeKey secondary_key = deserializeKey(record_ptr);
    auto secondary_key_size = getSerializedKeySize(secondary_key);

    // 主键就存储在二级索引键之后
    return deserializeKey(record_ptr + secondary_key_size);
}

int DBPage::findLeafKeyIndex(BPlusTreeKey key) const
{

    if (!key.has_value())
        return -1;
    int low = 0, high = getNumRecords() - 1;
    while (low <= high)
    {
        int mid = low + (high - low) / 2;
        int cmp = compareKeys(getLeafKey(mid), key);

        if (cmp == 0) // getLeafKey(mid) == key
            return mid;
        if (cmp < 0) // getLeafKey(mid) < key
            low = mid + 1;
        else // getLeafKey(mid) > key
            high = mid - 1;
    }
    return -1; // 未找到
}
uint32_t DBPage::findChildPage(const BPlusTreeKey &key) const
{
    if (getPageType() == PageType::BPLUS_LEAF_PAGE)
    {
        throw std::runtime_error("叶子节点没有子页面");
    }
    if (!key.has_value())
    {
        return getLeftmostPointer();
    }
    int low = 0, high = getNumRecords() - 1;

    // 二分查找找到第一个大于等于 key 的键
    int result_index = -1; // 默认为最左指针
    while (low <= high)
    {
        int mid = low + (high - low) / 2;
        if (compareKeys(getKey(mid), key) >= 0)
        {
            result_index = mid;
            high = mid - 1;
        }
        else
        {
            low = mid + 1;
        }
    }

    if (result_index == -1)
    {
        // 如果 key 小于所有键，跟随最左指针
        return getLeftmostPointer();
    }
    else
    {
        // 否则，跟随 key[result_index - 1] 对应的指针
        return getInternalValue(result_index);
    }
}
bool DBPage::IsUnderflow(double threshold) const
{
    // 根节点特殊处理：根节点可以有任意少的记录（甚至只有一个指针），所以它永远不会下溢。
    // B+树的规则是根节点至少要有2个孩子，除非它也是叶子节点。
    // 简化处理：如果一个内部节点是根，我们允许它只有一个记录（即两个孩子指针）。
    // 如果一个叶子节点是根，我们允许它只有一个记录。
    if (isRoot())
    {
        // 对于根节点，只有当它完全为空时才考虑处理（这在B+树中通常不会发生）
        // 一个更严谨的规则：如果内部根节点孩子少于2个，则需要收缩树高。
        // 此处简化为根节点永不下溢。
        return false;
    }

    // 计算总可用数据空间，即排除页头的空间
    const uint32_t total_data_space = REAL_PAGE_SIZE - sizeof(PageHeader);

    // 计算当前数据占用的空间（记录数据 + 槽）
    const PageHeader *header = getHeader();
    const uint32_t current_data_space =
        (header->free_space_ptr - sizeof(PageHeader)) + // 记录数据区大小
        (header->num_records * sizeof(Slot));           // 槽数组大小

    // 判断当前数据占用空间是否小于总可用数据空间的一半
    return current_data_space < static_cast<uint32_t>(total_data_space * threshold);
}
bool DBPage::insertLeaf(const BPlusTreeKey &key, const Row &row, bool &is_space_enough)
{
    size_t key_size = getSerializedKeySize(key);
    size_t row_size = calculateRowSize(row);
    size_t record_size = key_size + row_size;
    std::vector<uint8_t> record_buffer(record_size);

    serializeKey(record_buffer.data(), key);
    serializeRow(record_buffer.data() + key_size, row);

    int insert_idx = 0;
    while (insert_idx < getNumRecords() && getKey(insert_idx) < key)
    {
        insert_idx++;
    }

    return insertRecord(insert_idx, record_buffer.data(), record_size, is_space_enough);
}
bool DBPage::insertLeaf(int index, const BPlusTreeKey &key, const Row &row, bool &is_space_enough)
{
    size_t key_size = getSerializedKeySize(key);
    size_t row_size = calculateRowSize(row);
    size_t record_size = key_size + row_size;
    std::vector<uint8_t> record_buffer(record_size);
    serializeKey(record_buffer.data(), key);
    serializeRow(record_buffer.data() + key_size, row);
    return insertRecord(index, record_buffer.data(), record_size, is_space_enough);
}
// For secondary index
bool DBPage::insertLeaf(const BPlusTreeKey &secondary_key, const BPlusTreeKey &primary_key, bool &is_space_enough)
{
    size_t secondary_key_size = getSerializedKeySize(secondary_key);
    size_t primary_key_size = getSerializedKeySize(primary_key);
    size_t record_size = secondary_key_size + primary_key_size;
    std::vector<uint8_t> record_buffer(record_size);

    serializeKey(record_buffer.data(), secondary_key);
    serializeKey(record_buffer.data() + secondary_key_size, primary_key);

    int insert_idx = 0;
    int num_records = getNumRecords();
    while (insert_idx < num_records && getKey(insert_idx) < secondary_key)
    {
        insert_idx++;
    }
    while (insert_idx < num_records && getKey(insert_idx) == secondary_key && getLeafValue(insert_idx) < primary_key)
    {
        insert_idx++;
    }
    return insertRecord(insert_idx, record_buffer.data(), record_size, is_space_enough);
}
bool DBPage::insertLeaf(int index, const BPlusTreeKey &secondary_key, const BPlusTreeKey &primary_key, bool &is_space_enough)
{
    size_t secondary_key_size = getSerializedKeySize(secondary_key);
    size_t primary_key_size = getSerializedKeySize(primary_key);
    size_t record_size = secondary_key_size + primary_key_size;
    std::vector<uint8_t> record_buffer(record_size);
    serializeKey(record_buffer.data(), secondary_key);
    serializeKey(record_buffer.data() + secondary_key_size, primary_key);
    return insertRecord(index, record_buffer.data(), record_size, is_space_enough);
}
// ------------------- 验证和调试 -------------------

void DBPage::updateChecksum()
{
    PageHeader *header = getHeader();
    header->checksum = 0; // 临时清零以计算校验和

    uint32_t checksum_val = 0;
    for (size_t i = 0; i < REAL_PAGE_SIZE; ++i)
    {
        // 简单的XOR校验和
        checksum_val = (checksum_val << 1) | (checksum_val >> 31); // 循环移位
        checksum_val ^= data_[i];
    }
    header->checksum = checksum_val;
}

bool DBPage::validate() const
{
    const PageHeader *header = getHeader();
    uint32_t stored_checksum = header->checksum;

    // 创建临时副本来计算校验和
    std::vector<uint8_t> temp_data = data_;
    PageHeader *temp_header = reinterpret_cast<PageHeader *>(temp_data.data());
    temp_header->checksum = 0;

    uint32_t calculated_checksum = 0;
    for (size_t i = 0; i < REAL_PAGE_SIZE; ++i)
    {
        calculated_checksum = (calculated_checksum << 1) | (calculated_checksum >> 31);
        calculated_checksum ^= temp_data[i];
    }

    return stored_checksum == calculated_checksum;
}
uint32_t DBPage::getLeftmostPointer() const
{
    if (isLeaf())
    {
        // 叶子节点没有这个概念，可以抛出异常或返回无效值
        return INVALID_PAGE_ID;
    }
    return getHeader()->leftmost_child_page_id;
}

void DBPage::setLeftmostPointer(uint32_t page_id)
{
    if (isLeaf())
    {
        // 同样，对叶子节点操作是无效的
        return;
    }
    getHeader()->leftmost_child_page_id = page_id;
    updateChecksum(); // 更新校验和
}
void DBPage::MoveRecordFrom(DBPage *sibling_page, int sibling_index, int dest_index)
{
    if (!sibling_page || sibling_index < 0 || dest_index < 0)
    {
        throw std::invalid_argument("无效的参数");
    }
    if (sibling_page->getPageType() != getPageType())
    {
        throw std::invalid_argument("兄弟页类型不匹配");
    }
    // 获取兄弟页的记录
    auto [record_data, record_size] = sibling_page->GetRecord(sibling_index);
    if (!record_data)
    {
        throw std::runtime_error("无法获取兄弟页的记录");
    }

    // 插入到目标页
    bool is_space_enough = false;
    if (!insertRecord(dest_index, record_data, record_size, is_space_enough) && !is_space_enough)
    {
        throw std::runtime_error("目标页空间不足");
    }

    // 从兄弟页删除记录
    sibling_page->DeleteRecord(sibling_index);
}

int DBPage::findChildIndex(uint32_t child_page_id) const
{
    if (isLeaf())
    {
        throw std::runtime_error("叶子节点没有子页面");
    }

    // 检查最左指针
    if (getLeftmostPointer() == child_page_id)
    {
        return -1; // 最左指针没有对应的槽，返回-1表示
    }

    // 遍历所有槽，查找对应的子页面ID
    for (int i = 0; i < getNumRecords(); ++i)
    {
        if (getInternalValue(i) == child_page_id)
        {
            return i;
        }
    }

    return -2; // 未找到
}
void DBPage::MoveAllTo(DBPage *recipient_page)
{
    if (!recipient_page)
    {
        throw std::invalid_argument("Recipient page is null.");
    }
    if (getPageType() != recipient_page->getPageType())
    {
        throw std::invalid_argument("DBPage type mismatch.");
    }

    // 将当前页的所有记录移动到目标页
    int num_records = getNumRecords();
    int target_num_records = recipient_page->getNumRecords();
    for (int i = 0; i < num_records; ++i)
    {
        auto [record_data, record_size] = GetRecord(i);
        if (!record_data)
        {
            throw std::runtime_error("无法获取当前页的记录");
        }

        bool is_space_enough = false;
        int index = target_num_records + i;
        if (!recipient_page->insertRecord(index, record_data, record_size, is_space_enough) && !is_space_enough)
        {
            throw std::runtime_error("目标页空间不足");
        }
    }

    // 清空当前页的所有记录
    for (int i = getNumRecords() - 1; i >= 0; --i)
    {
        DeleteRecord(i);
    }
}
bool DBPage::insertInternal(int index, BPlusTreeKey key, uint32_t child_page_id, bool &is_space_enough)
{
    if (index < 0 || index > getNumRecords())
    {
        throw std::invalid_argument("无效的索引");
    }

    size_t key_size = getSerializedKeySize(key);
    size_t record_size = key_size + sizeof(uint32_t);
    std::vector<uint8_t> record_buffer(record_size);
    serializeKey(record_buffer.data(), key);
    memcpy(record_buffer.data() + key_size, &child_page_id, sizeof(uint32_t));

    // 尝试插入记录
    bool insert_success = insertRecord(index, record_buffer.data(), record_size, is_space_enough);
    if (!insert_success && !is_space_enough)
    {
        throw std::runtime_error("目标页空间不足");
    }

    return insert_success;
}
void DBPage::printMetaInfo() const
{
    const PageHeader *header = getHeader();
    std::cout << "================ 页元信息 ================" << std::endl;
    std::cout << "页ID: " << header->page_id << std::endl;
    std::cout << "父页ID: " << header->parent_page_id << std::endl;

    std::string type_str;
    switch (header->page_type)
    {
    case PageType::BPLUS_LEAF_PAGE:
        type_str = "B+树叶子节点";
        break;
    case PageType::BPLUS_INTERNAL_PAGE:
        type_str = "B+树内部节点";
        break;
    default:
        type_str = "未知";
        break;
    }

    std::cout << "页类型: " << type_str << " (层级 " << header->level << ")" << std::endl;
    std::cout << "记录数量: " << header->num_records << std::endl;

    if (isLeaf())
    {
        std::cout << "前一页ID: " << header->prev_page_id
                  << ", 后一页ID: " << header->next_page_id << std::endl;
    }

    std::cout << "空闲空间指针: " << header->free_space_ptr << std::endl;
    std::cout << "空闲空间大小: " << getFreeSpaceSize() << " 字节" << std::endl;
    std::cout << "校验和: 0x" << std::hex << header->checksum << std::dec << std::endl;
    std::cout << "验证状态: " << (validate() ? "正常" : "损坏") << std::endl;
    std::cout << "================================================" << std::endl;
}